#ifndef _MATH_EXCEPT_H_
#define _MATH_EXCEPT_H_

#include "./math_def.h"

#ifdef ALLOW_EXCEPT
#define DEBUG_DIV_ZERO
#endif

namespace Mathematics {
	//! Exception class for handling division by 0.0.
	/*!
		Usually the natural solution would be divide for a little number (e.g.: 0.001),
		to see the operation tendencies, but one can use another solution.
	*/
	template <class Num>
		class DivisionByZeroException: public Wtb {
		private:
				// -attributes-
			/*! string containing error log. */
			string	error;
			/*! object being divided. */
			Num		num;
			
				// -private methods-
			
		public:
				// -constructors-
			/*! 
				Constructor
				
				\param message The message to be presented.
				\param dividing_value The numerator.
			*/
			DivisionByZeroException(const string &message, const Num &dividing_value)
				:Wtb(),error(message),num(dividing_value){
#ifdef DEBUG_DIV_ZERO
				debug_function_info( "Constructor: ", "DivisionByZeroException", (int) &( *this ), sizeof( *this ) );
				cout << "Dividing: " << num << pendl << endl;
#endif
			};
			/*! 
				Destructor
			*/
			virtual ~DivisionByZeroException(){
#ifdef DEBUG_DIV_ZERO
				debug_function_info( "Destructor: ", "DivisionByZeroException", (int) &( *this ), sizeof( *this ) );
				cout << "Dividing: " << num << pendl << endl;
#endif
			};
			
			// -getters & setters-
			//! getter for the error message
			inline string getError() const {
				return error;
			};
			//! getter for the num object
			inline Num getNum() const {
				return num;
			};
			
			// -operators-
			
			// -public methods-
			/*! Convertion to string. */
			virtual inline string toS() const {
				return error + "\nDividing " + num.toS() + " by zero.";
			};
		};

	//! class for leading exception caused by access beyond array limit.
	/*!
		stores the value of the access and the actual bound.
	*/
	class OutOfBoundsException: public Wtb{
	protected:
		/*! string containing error log. */
		string	error;
		/*! violated bound value. */
		uint		bound;
		/*! acessed index. */
		uint		access;
		
	public:
		/*! 
			Constructor
			
			\param message The message to be presented.
			\param bound The broken bound.
			\param access The index used.
		*/
		OutOfBoundsException(const string &message, const uint &bound, const uint &access);
		/*! 
			Copy Constructor
			
			\param original The object to be copied.
		*/
		OutOfBoundsException(const OutOfBoundsException &original);
		/*! 
			Destructor
		*/
		~OutOfBoundsException();
		
			// -getters & setters-
		//! getter for the error message
		inline string getError() const { return error; };
		//! getter for the bound
		inline uint getBound() const { return bound; };
		//! getter for the access
		inline uint getAccess() const { return access; };
		
			// -operators-
		
			// -public methods-
		
			// -read & write-
		/*! Convertion to string. */
		virtual inline string toS() const {
			return error + string(" Acessing index ") + itos((int)access) + string(" in ") + itos((int)bound);
		};
		/*! 
			Writes the value of the Exception in an opened file.
			
			\param parq Pointer to the opened file.
			\return boolean indicating failure or success of the operation
		*/
		virtual bool filePrint( FILE *parq = stdin ) const ;
	};
	
};

#endif
